package com.chendx.store.user.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.chendx.model.common.dtos.ResponseResult;
import com.chendx.model.common.enums.AppHttpCodeEnum;
import com.chendx.model.goods.pojo.Pref;
import com.chendx.model.user.dto.UserPrefDto;
import com.chendx.model.user.pojo.User;
import com.chendx.model.user.pojo.UserPref;
import com.chendx.model.user.vo.UserPrefVo;
import com.chendx.store.common.constants.cart.CartConstants;
import com.chendx.store.user.feign.GoodsFeign;
import com.chendx.store.user.mapper.UserPrefMapper;
import com.chendx.store.user.service.UserPrefService;
import com.chendx.store.utils.AppThreadLocalUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * Created by chendx on 2022/4/19.
 */
@Service
public class UserPrefServiceImpl extends ServiceImpl<UserPrefMapper,UserPref> implements UserPrefService {

    @Autowired
    private StringRedisTemplate redisTemplate;
    @Autowired
    private GoodsFeign goodsFeign;
    @Override
    public ResponseResult receivePref(String prefId) {
        User user = AppThreadLocalUtils.get();
        if (user == null || user.getId() == null || user.getUsername() == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN);
        }
        String username = user.getUsername();
        if (StringUtils.isEmpty(prefId)){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        UserPref userPref = new UserPref();
        userPref.setStatus("0");
        userPref.setPrefId(prefId);
        userPref.setUsername(username);
        userPref.setReceiveTime(new Date());
        try {
            save(userPref);
        } catch (Exception e) {
            e.printStackTrace();
            return ResponseResult.errorResult(AppHttpCodeEnum.SERVER_ERROR);
        }
        ResponseResult res = goodsFeign.one(prefId);
        UserPrefVo userPrefVo = new UserPrefVo();
        BeanUtils.copyProperties(userPref,userPrefVo);
        if (res.getCode() == 0){
            Pref pref = JSON.parseObject(JSON.toJSONString(res.getData()), Pref.class);
            userPrefVo.setPref(pref);
        }
        redisTemplate.boundHashOps(CartConstants.RECEIVER_PREF + userPref.getUsername()).put(prefId, JSON.toJSONString(userPrefVo));
        return ResponseResult.okResult(userPrefVo);
    }

    @Override
    public ResponseResult loadUserPref() {
        User user = AppThreadLocalUtils.get();
        if (user == null || user.getId() == null || user.getUsername() == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN);
        }
        String username = user.getUsername();
        List<UserPref> userPrefs = new ArrayList<>();
        List<UserPrefVo> userPrefvos = new ArrayList<>();
        Boolean flag = redisTemplate.hasKey(CartConstants.RECEIVER_PREF + username);
        if (flag){
            List<Object> objectList = redisTemplate.boundHashOps(CartConstants.RECEIVER_PREF + username).values();
            userPrefvos = JSON.parseArray(objectList.toString(), UserPrefVo.class);
        }else{
            userPrefs = list(Wrappers.<UserPref>lambdaQuery().eq(UserPref::getUsername, username));
            if (userPrefs.size() > 0){
                for (UserPref userPref : userPrefs){
                    UserPrefVo userPrefVo = new UserPrefVo();
                    userPrefVo.setPrefId(userPref.getPrefId());
                    userPrefVo.setUsername(userPref.getUsername());
                    userPrefVo.setReceiveTime(userPref.getReceiveTime());
                    userPrefVo.setPrefId(userPref.getPrefId());
                    userPrefVo.setStatus(userPref.getStatus());
                    userPrefVo.setUseTime(userPref.getUseTime());
                    userPrefVo.setUserId(userPref.getUserId());
                    ResponseResult res = goodsFeign.one(userPref.getPrefId());
                    if (res.getCode() == 0){
                        String jsonString = JSON.toJSONString(res.getData());
                        Pref pref = JSON.parseObject(jsonString, Pref.class);
                        userPrefVo.setPref(pref);
                    }
                    userPrefvos.add(userPrefVo);
                    redisTemplate.boundHashOps(CartConstants.RECEIVER_PREF + username).put(userPref.getPrefId(),JSON.toJSONString(userPrefVo));
                }
            }
        }
        return ResponseResult.okResult(userPrefvos);
    }

    @Override
    public ResponseResult usePref(String prefId) {
        User user = AppThreadLocalUtils.get();
        if (user == null || user.getId() == null || user.getUsername() == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN);
        }
        String username = user.getUsername();
        Object o = redisTemplate.boundHashOps(CartConstants.RECEIVER_PREF + username).get(prefId);
        UserPref userPref = JSON.parseObject(String.valueOf(o),UserPref.class);
        userPref.setStatus("1");
        userPref.setUseTime(new Date());
        redisTemplate.boundHashOps(CartConstants.RECEIVER_PREF + username).put(prefId,JSON.toJSONString(userPref));
        return null;
    }

    @Override
    public ResponseResult updateUserPref(UserPrefDto dto) {
        User user = AppThreadLocalUtils.get();
        if (user == null || user.getId() == null || user.getUsername() == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN);
        }
        String username = user.getUsername();
        if (dto == null){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        update(Wrappers.<UserPref>lambdaUpdate().eq(UserPref::getPrefId,dto.getPrefId()).set(UserPref::getStatus,dto.getStatus()));
        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }
}
